﻿#region
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using System.Windows.Forms;

#endregion

namespace MidnightPeach.EdmxTransformer
{
    public static class WinformUtility
    {
        #region InvokeIfRequired
        public static void InvokeIfRequired(this Control control, Action action)
        {
            if (control.InvokeRequired)
                control.Invoke(action);
            else
                action();
        }

        public static void InvokeIfRequired<T>(this Control control, Action<T> action, T arg)
        {
            if (control.InvokeRequired)
                control.Invoke(action, arg);
            else
                action(arg);
        }

        public static void InvokeIfRequired<T1, T2>(this Control control, Action<T1, T2> action, T1 arg1, T2 arg2)
        {
            if (control.InvokeRequired)
                control.Invoke(action, arg1, arg2);
            else
                action(arg1, arg2);
        }

        public static void InvokeIfRequired<T1, T2, T3>(this Control control, Action<T1, T2, T3> action, T1 arg1, T2 arg2,
            T3 arg3)
        {
            if (control.InvokeRequired)
                control.Invoke(action, arg1, arg2, arg3);
            else
                action(arg1, arg2, arg3);
        }

        public static void InvokeIfRequired<T1, T2, T3, T4>(this Control control, Action<T1, T2, T3, T4> action, T1 arg1,
            T2 arg2, T3 arg3, T4 arg4)
        {
            if (control.InvokeRequired)
                control.Invoke(action, arg1, arg2, arg3, arg4);
            else
                action(arg1, arg2, arg3, arg4);
        }

        public static object InvokeIfRequired(this Control control, Func<object> func)
        {
            if (control.InvokeRequired)
                return control.Invoke(func);
            else
                return func();
        }

        public static object InvokeIfRequired<T>(this Control control, Func<T, object> func, T arg)
        {
            if (control.InvokeRequired)
                return control.Invoke(func, arg);
            else
                return func(arg);
        }

        public static object InvokeIfRequired<T1, T2>(this Control control, Func<T1, T2, object> func, T1 arg1, T2 arg2)
        {
            if (control.InvokeRequired)
                return control.Invoke(func, arg1, arg2);
            else
                return func(arg1, arg2);
        }

        public static object InvokeIfRequired<T1, T2, T3>(this Control control, Func<T1, T2, T3, object> func, T1 arg1, T2 arg2,
            T3 arg3)
        {
            if (control.InvokeRequired)
                return control.Invoke(func, arg1, arg2, arg3);
            else
                return func(arg1, arg2, arg3);
        }

        public static object InvokeIfRequired<T1, T2, T3, T4>(this Control control, Func<T1, T2, T3, T4, object> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
        {
            if (control.InvokeRequired)
                return control.Invoke(func, arg1, arg2, arg3, arg4);
            else
                return func(arg1, arg2, arg3, arg4);
        }
        #endregion

        public static bool AskSureToDelete()
        {
            return Ask("정말 삭제하시겠습니까?");
        }

        public static bool Ask(string message, MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1)
        {
            return
                MessageBox.Show(message, "질문", MessageBoxButtons.YesNo, MessageBoxIcon.Question,
                    defaultButton) == DialogResult.Yes;
        }

        public static List<T> GetChildren<T>(this Control container) where T : class
        {
            List<T> controls = new List<T>();

            GetChildrenCore(container, controls);

            return controls;
        }

        private static void GetChildrenCore<T>(this Control container, List<T> controls) where T : class
        {
            var fields = container.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
            foreach (var field in fields)
            {
                if (field.FieldType.IsSubclassOf(typeof (UserControl)))
                {
                    GetChildrenCore((UserControl) field.GetValue(container), controls);
                }

                //                if (field.FieldType.IsSubclassOf(typeof(T))) // T 가 인터페이스이면 동작하지 않음
                if (typeof (T).IsAssignableFrom(field.FieldType))
                {
                    T control = (T) field.GetValue(container);

                    // container가 ApprovalWizardForm인 경우 SnapControl이 필드로 인식됨. 이유 불상.
                    if (control != null)
                        controls.Add(control);
                }
            }
        }

        public static void SetDefaultFont(string fontName = "굴림", float size = 9)
        {
//            if (Environment.OSVersion.Version.Major >= 6 && Environment.OSVersion.Version.Minor >= 2)
//                AppearanceObject.DefaultFont = new Font(fontName, size);
        }

        public static string GetIP()
        {
            string url = "http://checkip.dyndns.org";
            WebRequest req = WebRequest.Create(url);
            WebResponse resp = req.GetResponse();
            StreamReader sr = new StreamReader(resp.GetResponseStream());
            string response = sr.ReadToEnd().Trim();
            string[] a = response.Split(':');
            string a2 = a[1].Substring(1);
            string[] a3 = a2.Split('<');
            string a4 = a3[0];
            return a4;
        }
    }
}